/* BSQReader.java 
 * Created on September 20, 2004, 7:23 PM
 */

package edu.temple.GUS.MMA.io;
import edu.temple.GUS.MMA.DataTypes.MMAGrid;
import edu.temple.GUS.MMA.DataTypes.MMAHyperCube;
import edu.temple.GUS.MMA.DataTypes.MMASpaceCube;
import edu.temple.GUS.MMA.DataTypes.MMATimeCube;
import edu.temple.GUS.MMA.DataTypes.MMATimeSeries;
import java.io.*;
import java.util.*;
/**
 *
 * @author  rkhanna
 */
public class BSQReader 
{
     private static String cubetype="";
     private static int countrow=0;
     private static int X;
     private static int Y;
     private static int Z;
     private static int T;
     private static int xll;
     private static int yll;     
     private static int noData;     
     private static int xResolution;
     private static int yResolution;
     private static int zResolution; 
     private static int tResolution;     
     private static int tempint=0;
     private static String path="";    
     private static String headerfile="";

    /** Creates a new instance of BSQReader */

     
     public static boolean validate(String gridtype, String path, String filename) 
    {    
        String cubetype="";
        String data="";        
        headerfile = filename;
        countrow=0;

          try { 
           File f = new File(path +  headerfile); 
           FileInputStream fis = new FileInputStream(f); 
           BufferedInputStream bis = new BufferedInputStream(fis); 
           BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
           
	   bigloop:	
           while ( (data=myInput.readLine()) != null )
           {
               countrow++;  	                    
              // convert every row in header file except 1st to int 		
                if((countrow!=1) && (countrow<11))
		      tempint = Integer.parseInt(data);			 		
               System.out.println("Called from validate Count Row::" + countrow + " TempInt:" + tempint);               
              // capture X, Y, Z & T coordinates & resolutions
        	if(countrow==2)
                        X = tempint;
               else if(countrow==3)
        		Y = tempint;
              	else if(countrow==4)
        		Z = tempint;
                else if(countrow==5)
        		T = tempint;              
                else if(countrow==6)
                	xResolution = tempint;              
                else if(countrow==7)
        		yResolution = tempint;              
                else if(countrow==8)
        		zResolution = tempint;              
                else if(countrow==9)
        		tResolution = tempint;              
                else if(countrow==10)
        		noData = tempint;              
                else if(countrow==11)
        		xll = tempint;              
                else if(countrow==12)
        		yll = tempint;              
               
               if(gridtype.equals("grid"))
               {    
                    if( ( (countrow==4)||(countrow==5)||(countrow==8)||(countrow==9) ) && (tempint!=0) ) 
                    {    
                        System.out.println("Gird's Z, T, Resolution of Z, Resolution of T has to be zero");
                        return true;                        
                    }
               }     

               if(gridtype.equals("timecube"))
               {    
                    if( ( (countrow==4)||(countrow==8) ) && (tempint!=0) ) 
                    {    
                        System.out.println("Timecube's Z & Resolution of Z has to be zero");
                        return true;                        
                    }    
               }
               
               if(gridtype.equals("spacecube"))
               {    
                    if( ( (countrow==5)||(countrow==9) ) && (tempint!=0) ) 
                    {    
                        System.out.println("Spacecube's t & Resolution of t has to be zero");
                        return true;                        
                    }    
               }          
               
               if(gridtype.equals("timeseries"))
               {    
                    if( ( (countrow==2)||(countrow==3)||(countrow==4)||(countrow==6)||(countrow==7)||(countrow==8) ) && (tempint!=0) ) 
                    {    
                        System.out.println("Timeseries's X, Y, Z, Resolution of X, Resolution of Y, Resolution of Z  has to be zero");
                        return true;                        
                    }    
               }          
             }// end of while   
             }catch (IOException e) 
            { 
           // catch io errors from FileInputStream or readLine() 
           System.out.println("Uh oh, got an IOException error!" + e.getMessage()); 
            }                       
        return false;
    }
    
    
     
     public static MMAGrid readGrid(String path, String filename)
    {   
        System.out.println("Readgrid called");
        System.out.println("1");
        boolean flag = validate("grid", path, filename); 
        System.out.println("2");
        if (flag)
              return null;        
        float arr[][] =  new float[Y][X];                	
        String thisLine="";        
        int i=0;
        int j=0;
        String file1= new String(path+"1.dat");
        try
        {
        FileInputStream fis = new FileInputStream(file1);
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
	while ((thisLine = myInput.readLine()) != null) 
	{  
          // scan it line by line
          System.out.println(thisLine);
	  StringTokenizer st = new StringTokenizer(thisLine);
	  i=0; 	
	  while(st.hasMoreTokens())
          {    
              if(i>=X)
                break;              
             arr[j][i] = Float.valueOf(st.nextToken()).floatValue();
	    // System.out.println(x + "::::" + y + "::" + arr[x][y]);	
             i++;
          }   
          j++;          
        }// end of while
        }catch(Exception e) {System.out.println("Exception thrown from readGrid" + e);}
        MMAGrid gridobj = new MMAGrid();
        gridobj.putX(X);
        gridobj.putY(Y);
        gridobj.putXResolution(xResolution);
        gridobj.putYResolution(yResolution);
        gridobj.putData(arr);        
        gridobj.putNoData(noData);
        gridobj.putXLL(xll);
        gridobj.putYLL(yll);      
        System.out.println("XX" + X);
        System.out.println("YY" + Y);
        
        for(j=0;i<X;i++)
            for(i=0;j<Y;j++)
                System.out.print(arr[j][i]);
             //  System.out.println("i  ::"+"j  ::"+arr[i][j]);
        return gridobj;
    }
    
    
     
     
    public static MMATimeCube readTimeCube(String path, String filename)
    {
        validate("timecube", path, filename); 
        System.out.println("Initialise Timecube array called" + X + ":::" + Y+ ":::" + T);
        float arr[][][] =  new float[T][Y][X];                
        String thisLine="";        
        int i=0;
        int j=0;
        int openfile=0;
        for(int k=0;k<T;k++)
        {
            openfile=k+1;
            String file1= new String(path+openfile+".dat");
            try
            {
            FileInputStream fis = new FileInputStream(file1);
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
                while ((thisLine = myInput.readLine()) != null) 
                {  
                // scan it line by line
                System.out.print(thisLine);
                StringTokenizer st = new StringTokenizer(thisLine);
                i=0; 	
                    while(st.hasMoreTokens())
                    {    
                         if(i>=X)
                             break;                        
                    arr[k][j][i] = Float.valueOf(st.nextToken()).floatValue();
        	    //System.out.println(k+ "::" +j + "::" + i + "::" + arr[k][j][i]);	
                    i++;
                    }   
                j++;
                }// end of while
            j=0;
            fis.close();
            bis.close();
            myInput.close();
            }catch(Exception e) {System.out.println("Exception thrown from initialiseGridArray" + e);}
        
        System.out.println("XX" + X);
        System.out.println("YY" + Y);
        System.out.println("ZZ" + T);
        }// end of for
        
        MMATimeCube timecubeobj = new MMATimeCube();
        timecubeobj.putX(X);
        timecubeobj.putY(Y); 
        timecubeobj.putT(T);
        timecubeobj.putXResolution(xResolution);
        timecubeobj.putYResolution(yResolution);                
        timecubeobj.putTResolution(tResolution);
        timecubeobj.putNoData(noData);
        timecubeobj.putData(arr);        
        timecubeobj.putXLL(xll);
        timecubeobj.putYLL(yll);      
        return timecubeobj;
    }
    
    
    
    public static MMASpaceCube readSpaceCube(String path, String filename)
    {            
        validate("spacecube", path, filename); 

        System.out.println("Initialise Spacecube array called" + X + ":::" + Y+ ":::" + Z);
        float arr[][][] =  new float[Z][Y][X];                
        String thisLine="";        
        int i=0;
        int j=0;
        int openfile=0;
        
        for(int k=0;k<Z;k++)
        {
            openfile=k+1;
            String file1= new String(path+openfile+".dat");
                try
                {
                FileInputStream fis = new FileInputStream(file1);
                BufferedInputStream bis = new BufferedInputStream(fis);
                BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
                    while ((thisLine = myInput.readLine()) != null) 
                    {  
                    // scan it line by line
                    System.out.println(thisLine);
                    StringTokenizer st = new StringTokenizer(thisLine);
                    i=0; 	
                        while(st.hasMoreTokens())
                        {    
                         if(i>=X)
                             break;                            
                        arr[k][j][i] = Float.valueOf(st.nextToken()).floatValue();
                       // System.out.println(k+ "::" +j + "::" + i + "::" + arr[k][j][i]);	
                        i++;
                        }   
                    j++;
                    }// end of while
                j=0;
                fis.close();
                bis.close();
                myInput.close();
            }catch(Exception e) {System.out.println("Exception thrown from initialiseGridArray" + e);}
        
        System.out.println("XX" + X);
        System.out.println("YY" + Y);
        System.out.println("ZZ" + Z);
        }
        
        MMASpaceCube spacecubeobj = new MMASpaceCube();
        spacecubeobj.putX(X);
        spacecubeobj.putY(Y);        
        spacecubeobj.putZ(Z);        
        spacecubeobj.putXResolution(xResolution);
        spacecubeobj.putYResolution(yResolution);
        spacecubeobj.putZResolution(zResolution);
        spacecubeobj.putNoData(noData);
        spacecubeobj.putData(arr);        
        spacecubeobj.putXLL(xll);
        spacecubeobj.putYLL(yll);      

        for(int k=0;k<Z;k++)
            for(j=0;j<Y;j++)
                for(i=0;i<X;i++)
                    System.out.print("");
              //  System.out.println("i  ::"+"j  ::"+arr[k][j][i]);
        return spacecubeobj;
    }
    
    
    
    public static MMAHyperCube readHyperCube(String path, String filename)
    {
        validate("hypercube", path, filename); 
        System.out.println("Initialise Hypercube array called" + X + ":::" + Y+ ":::" + Z +":::" + T);
        float arr[][][][] =  new float[T][Z][Y][X];                
        String thisLine="";        
        int i=0;
        int j=0;
        int filecount=0;
        int nooffiles=T*Z;
        System.out.println("Reading HyperCube.......");
        
        for(int l=0;l<T;l++)
            for(int k=0;k<Z;k++)
            {
            ++filecount;
            String file1= new String(path+filecount+".dat");
                try
                {
                FileInputStream fis = new FileInputStream(file1);
                BufferedInputStream bis = new BufferedInputStream(fis);
                BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
                    while ((thisLine = myInput.readLine()) != null) 
                    {  
                    // scan it line by line
                    //System.out.println(thisLine);
                    StringTokenizer st = new StringTokenizer(thisLine);
                         while(st.hasMoreTokens())
                        {    
                         if(i>=X)
                             break;
                        arr[l][k][j][i] = Float.valueOf(st.nextToken()).floatValue();
                        i++;
                        }   
                    j++;
                    i=0;
                     }// end of while
                i=0;
                j=0;
                myInput.close();
                bis.close();
                fis.close();              
                }catch(Exception e) {System.out.println("Exception thrown from initialiseGridArray" + e);}
            /*System.out.println("XX" + X);
            System.out.println("YY" + Y);
            System.out.println("ZZ" + Z);
            System.out.println("TT" + T);        
             */
            }// end of for 
        
        
        MMAHyperCube hypercubeobj = new MMAHyperCube();
        hypercubeobj.putX(X);
        hypercubeobj.putY(Y);                
        hypercubeobj.putZ(Z);        
        hypercubeobj.putT(T);        
        hypercubeobj.putXResolution(xResolution);
        hypercubeobj.putYResolution(yResolution);        
        hypercubeobj.putZResolution(zResolution);        
        hypercubeobj.putTResolution(tResolution);
        hypercubeobj.putNoData(noData);
        hypercubeobj.putData(arr);        
        hypercubeobj.putXLL(xll);
        hypercubeobj.putYLL(yll);      
        
        
      for(int l=0; l<T; l++)
        for(int k=0;k<Z;k++)
            for(j=0;j<Y;j++)
                for(i=0;i<X;i++)
                    System.out.print("");
              //  System.out.println(l+" ::"+k + "  ::  "+  j +"  ::  "+i + "  ::::::"+arr[l][k][j][i]);        
    return hypercubeobj;
    }        // end of MMAHypercube
    
    
        
    public static MMATimeSeries readTimeSeries(String path, String filename)
    {
        validate("timeseries", path, filename); 
        System.out.println("Initialise Timeseries array called" + X + ":::" + Y+ ":::" + T);
        float arr[] =  new float[T];                
        String thisLine="";        
        int i=0;
        int j=0;
            String file1= new String(path + "1.dat");
            try
            {
            FileInputStream fis = new FileInputStream(file1);
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedReader myInput = new BufferedReader(new InputStreamReader(bis));
                while ((thisLine = myInput.readLine()) != null) 
                {  
                // scan it line by line
                System.out.print(thisLine);
                StringTokenizer st = new StringTokenizer(thisLine);
                    while(st.hasMoreTokens())
                    {    
                    arr[i] = Float.valueOf(st.nextToken()).floatValue();
        	    System.out.println("::arr[" + i + "]::" + arr[i]);	
                    i++;
                    }   
                }// end of while
            fis.close();
            bis.close();
            myInput.close();
            }catch(Exception e) {System.out.println("Exception thrown from initialiseGridArray" + e);}
        
        System.out.println("XX" + X);
        System.out.println("YY" + Y);
        System.out.println("ZZ" + T);
        MMATimeSeries tsobj = new MMATimeSeries();                
        
        tsobj.putT(T);
        tsobj.putTResolution(tResolution);
        tsobj.putData(arr);    
        tsobj.putNoData(noData);        
        tsobj.putXLL(xll);
        tsobj.putYLL(yll);      

                //for(i=0;i<arr.length;i++)
               // System.out.println("i  ::"+"j  ::"+arr[i]);
        
       return tsobj;    
    }// end of method readTimeSeries        
}// end of class    
